/* 
 * Author: Vassilis
 */

#ifndef _LEVELMAP_H
#define	_LEVELMAP_H

#include "SelfDrawable.h"
#include "NonCopyable.h"
#include "Grid.h"
#include "Tile.h"
#include "Tileset.h"
#include <list>
#include <map>
#include <vector>

struct EnviromentalData
{
    Math::Vector2F gravity;
    Math::Vector2F wind;
    float ressistance;
};

/**
 * A class describing the tile map. It includes the defenitions of its tiles and tilesets.
 */
class LevelMap : public SelfDrawable, NonCopyable
{
private:
    
    /**
     * The grid spatial data structure.
     */
    Grid<int> *m_grid;
    
    /**
     * A vector holding all different tiles.
     */
    std::vector<Tile> m_tiles;
    
    /**
     * A datastructure to store all tilesets.S
     * Each tileset has as a key the number of its first tile.
     * 
     * ex. If we have 3 tilesets and each has 32 tiles
     * the map will be as follows:
     * [1] - FirstTileset
     * [33] - SecondTileset
     * [65]- ThirdTileset
     */
    std::map<int, Tileset> m_tilesets;
    
    /**
     * The size of map in number of tiles.
     */
    unsigned m_width, m_height;
    
    /**
     * The dimensions of each tile of this map.
     */
    unsigned m_tileWidth, m_tileHeight;
    
    /**
     * The background image of this map.
     * Note that this image is not drawn by map.
     */
    SelfDrawable* m_background;
    
    /**
     * Data used by other objects as physicsManager.
     */
    EnviromentalData enviromentalData;
    
public:
    LevelMap();
    ~LevelMap();

    void SetSize(unsigned sWidth, unsigned sHeight);
    void SetTileSize(unsigned sTileWidth, unsigned sTileHeight);
    /**
     * Register a pre existing tileset.
     * @param toRegister
     */
    void RegisterTileset(const Tileset &toRegister);
    
    /**
     * Register a new tileset into the map.
     * @param path 
     * @param file 
     * @param fgid 
     */
    void RegisterTileset(const std::string &path,const std::string& file,  int fgid);
    void RegisterTile(Tile &toRegister, int locX, int locY);
    void RegisterTileProperties(int gid, unsigned long flag);
    void ClearTiles();
    unsigned long GetTilelistPropsFromRPos(unsigned int x,unsigned int y);
    unsigned long GetTilelistProperties(unsigned int x,unsigned int y);
    
    virtual void Draw(sdl::GraphicsCore *gCore, Camera *camera);
    virtual int GetWidth() const;
    virtual int GetHeight() const;
    unsigned GetTileHeight() const;
    unsigned GetTileWidth() const;
    void SetBackground(Resource<gl::Texture>* background);
    SelfDrawable* GetBackground() const;
    
    /**
     * Returns the registered properties of the specified gid.
     * @param tile The tile to be returned ( if found )
     * @return true if found false otherwise.
     */
    bool GetTile(int gid,Tile& tile);
    
private:
    int SearchTile(const Tile &toFind);
};

#endif	/* _LEVELMAP_H */

